/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "csr_parser.h"
#include <mc/expr/function/call.h>
#include <mc/expr/function/parser.h>
#include <mc/log.h>
#include <mc/string.h>
#include <mc/format.h>
#include <regex>
#include <set>

using namespace mc::expr;
namespace devmon {
namespace csr_parser {

constexpr std::string_view MANAGEMENT_TOPOLOGY_KEY = "ManagementTopology";
constexpr std::string_view ANCHOR_KEY              = "Anchor";
constexpr std::string_view BUSES_KEY               = "Buses";
constexpr std::string_view OBJECTS_KEY             = "Objects";
constexpr std::string_view CONTAINER_KEY           = "Container";
constexpr std::string_view PARENT_KEY              = "@Parent";
constexpr std::string_view CHILDREN_KEY            = "@Children";
constexpr std::string_view DEFAULT_KEY             = "@Default";
constexpr std::string_view CONNECTORS_KEY          = "Connectors";
constexpr std::string_view IDENTIFY_MODE_KEY       = "IdentifyMode";
constexpr std::string_view POSITION_KEY            = "Position";
constexpr std::string_view CHIPS_KEY               = "Chips";
constexpr std::string_view REF_TAG                 = "#/";
constexpr std::string_view SYNC_TAG                = "<=/";
constexpr std::string_view EXPR_TAG                = "|>";
constexpr std::string_view SYSTEM_ID_KEY           = "SystemId";
constexpr std::string_view ID_KEY                  = "Id";
constexpr std::string_view MANAGER_ID_KEY          = "ManagerId";
constexpr std::string_view CHASSIS_ID_KEY          = "ChassisId";
constexpr int              COMPONENT_E2P           = 1;
constexpr int              MAX_EXPR_LEVEL          = 10;
constexpr int              DEFAULT_LIFE_CYCLE_ID   = 1;

constexpr std::string_view               CONNECTOR_VARIABLES[] = {"Slot",    "SystemId",  "ManagerId",     "Container",
                                                                  "GroupId", "ChassisId", "GroupPosition", "SilkText",
                                                                  "Id",      "Bom",       "AuxId",         "Buses"};
constexpr std::string_view               CSR_VARIABLES[]       = {"Slot",    "SystemId",  "ManagerId",     "Container",
                                                                  "GroupId", "ChassisId", "GroupPosition", "SilkText"};
constexpr std::string_view               REPLACE_VARIABLES[]   = {"DataVersion", "FormatVersion"};
constexpr std::string_view               IGNORED_CLASSES[]     = {"Accessor", "Scanner", "Cont", "ContBin", "Median"};
const std::map<std::string, mc::variant> DEFAULT_VALUES = {{"SystemId", 1}, {"ManagerId", "1"}, {"ChassisId", ""}};
const std::map<std::string, std::vector<std::string>> RENAME_PROPS = {{"SmcDfxInfo", {"Mapping"}}};

static uint64_t                                  g_max_group_id = 0;
static std::unordered_map<std::string, uint64_t> g_group_id_map;
static std::mutex                                g_group_id_map_mutex;

static uint64_t get_group_id(std::string position) {
    std::lock_guard<std::mutex> lock(g_group_id_map_mutex);
    if (g_group_id_map.find(position) != g_group_id_map.end()) {
        return g_group_id_map[position];
    }
    g_group_id_map[position] = ++g_max_group_id;
    return g_max_group_id;
}

static std::optional<mc::variant> get_value_from_dict(mc::dict& dict, std::string_view key) {
    if (!dict.contains(key)) {
        return std::nullopt;
    }
    return dict[key];
}

template <typename... Args>
static std::optional<mc::variant> get_value_from_dict(mc::dict& dict, std::string_view key,
                                                      Args... args) {
    if (!dict.contains(key) || !dict[key].is_dict()) {
        return std::nullopt;
    }
    auto inner_dict = dict[key].as_dict();
    return get_value_from_dict(inner_dict, args...);
}

raw_data_t::raw_data_t(std::string_view position, mc::dict& connector, const mc::dict& csr_data)
    : m_position(position), m_sdr_data(csr_data) {
    for (auto& item : CONNECTOR_VARIABLES) {
        if (connector.contains(item)) {
            m_context[item] = connector[item];
        } else if (DEFAULT_VALUES.find(std::string(item)) != DEFAULT_VALUES.end()) {
            m_context[item] = DEFAULT_VALUES.at(std::string(item));
        }
    }
    if (connector.contains("ObjectName")) {
        m_context["connector_name"] = connector["ObjectName"];
    }
    auto opt = get_value_from_dict(m_sdr_data, MANAGEMENT_TOPOLOGY_KEY);
    if (opt.has_value() && opt.value().is_dict()) {
        m_management_topology = opt.value().as_dict();
    }
    opt = get_value_from_dict(m_sdr_data, OBJECTS_KEY);
    if (opt.has_value() && opt.value().is_dict()) {
        m_objects = opt.value().as_dict();
    }
}

parse_task::parse_task(raw_data_t* data, std::string_view name) : m_data(data), m_name(name) {
}

void parse_task::run() {
    try {
        handle_run();
    } catch (std::exception& e) {
        wlog("csr parse task ${name} failed, position: ${position}, error: ${error}",
             ("name", m_name)("position", m_data->m_position)("error", e.what()));
    } catch (...) {
        wlog("csr parse task ${name} failed, position: ${position}", ("name", m_name)("position", m_data->m_position));
    }
}

parse_task& parse_task::next(parse_task& task) {
    task.run();
    return task;
}

parse_task& parse_task::run_and_next(parse_task& task) {
    run();
    task.run();
    return task;
}

void parse(std::string_view position, mc::dict& connector, const mc::dict& csr_data) {
    raw_data_t   data(position, connector, csr_data);
    match_task   match(&data, "match");
    rename_task  rename(&data, "rename");
    append_task  append(&data, "append");
    arrange_task arrange(&data, "arrange");
    analyze_task analyze(&data, "analyze");
    match.run_and_next(rename).next(append).next(arrange).next(analyze);
}

match_task::match_task(raw_data_t* data, std::string_view name) : parse_task(data, name) {
}

void match_task::handle_run() {
    auto opt = get_value_from_dict(m_data->m_sdr_data, MANAGEMENT_TOPOLOGY_KEY, ANCHOR_KEY, BUSES_KEY);
    if (!opt.has_value() || !opt.value().is_array()) {
        return;
    }
    auto                     current_buses = opt.value().as<std::vector<std::string>>();
    std::vector<std::string> parent_buses;
    if (m_data->m_context.contains(BUSES_KEY)) {
        parent_buses = m_data->m_context[BUSES_KEY].as<std::vector<std::string>>();
        if (parent_buses.size() != current_buses.size()) {
            wlog("position: {position}, unmatched anchor buses, parent number: {parent_buses}, "
                 "current number: {current_buses}",
                 ("position", m_data->m_position)("parent_buses", parent_buses.size())("current_buses",
                                                                                       current_buses.size()));
        }
    }
    m_data->m_bus_map.clear();
    m_data->m_extra_buses.clear();
    for (size_t i = 0; i < current_buses.size(); i++) {
        if (i < parent_buses.size()) {
            m_data->m_bus_map[current_buses[i]] = parent_buses[i];
        } else {
            m_data->m_extra_buses.push_back(current_buses[i]);
            m_data->m_bus_map[current_buses[i]] = current_buses[i];
        }
    }
}

rename_task::rename_task(raw_data_t* data, std::string_view name) : parse_task(data, name) {
}

static void replace_objects(std::vector<std::string>& members, string_map_t& objects_map, std::string_view position) {
    for (size_t i = 0; i < members.size(); i++) {
        if (objects_map.find(members[i]) == objects_map.end()) {
            objects_map[members[i]] = members[i] + "_" + std::string(position);
        }
        members[i] = objects_map[members[i]];
    }
}

mc::dict rename_task::replace_objects_name(mc::dict& objects, string_map_t& objects_map) {
    mc::mutable_dict result;
    for (auto& entry : objects) {
        auto key = entry.key.as<std::string>();
        if (m_data->m_bus_map.find(key) != m_data->m_bus_map.end()) {
            result[m_data->m_bus_map[key]] = entry.value;
        } else {
            if (objects_map.find(key) == objects_map.end()) {
                objects_map[key] = key + "_" + m_data->m_position;
            }
            result[objects_map[key]] = entry.value;
        }
    }
    return result;
}

void rename_task::rename_management_topology(string_map_t& objects_map) {
    if (!m_data->m_management_topology.has_value()) {
        return;
    }
    auto& topology                       = m_data->m_management_topology.value();
    objects_map[std::string(ANCHOR_KEY)] = std::string(ANCHOR_KEY);
    for (auto& entry : topology) {
        if (!entry.value.is_dict()) {
            continue;
        }
        mc::mutable_dict children = entry.value.as_dict();
        for (auto& child_entry : children) {
            if (!child_entry.value.is_array()) {
                continue;
            }
            auto members = child_entry.value.as<std::vector<std::string>>();
            if (child_entry.key == BUSES_KEY) {
                replace_objects(members, m_data->m_bus_map, m_data->m_position);
            } else {
                replace_objects(members, objects_map, m_data->m_position);
            }
            child_entry.value = members;
        }
    }
    m_data->m_sdr_data[MANAGEMENT_TOPOLOGY_KEY] = replace_objects_name(topology, objects_map);
}

replace_syntax_t rename_task::get_replace_syntax() {
    replace_syntax_t replace_syntax;
    for (auto& variable : CSR_VARIABLES) {
        if (m_data->m_context.contains(variable)) {
            replace_syntax["${" + std::string(variable) + "}"] = m_data->m_context[variable];
        }
    }
    for (auto& variable : REPLACE_VARIABLES) {
        auto syntax = "${" + std::string(variable) + "}";
        if (replace_syntax.find(syntax) == replace_syntax.end() && m_data->m_sdr_data.contains(variable)) {
            replace_syntax[syntax] = m_data->m_sdr_data[std::string(variable)];
        }
    }
    return replace_syntax;
}

static mc::variant rewrite_prop_value(bool is_numeric, mc::variant& prop_value, replace_syntax_t& replace_syntax) {
    if (!prop_value.is_string()) {
        return prop_value;
    }
    auto prop_str = prop_value.as<std::string>();
    for (auto& [key, value] : replace_syntax) {
        if (prop_str == key && is_numeric && value.is_numeric()) {
            return value;
        }
    }
    auto result = prop_str;
    for (auto& [key, value] : replace_syntax) {
        result = mc::string::replace_all(result, key, value.as_string());
    }
    return result;
}

static mc::variant rename_by_relation(std::string_view prop_name, mc::variant& prop_value, string_map_t& objects_map) {
    if (!prop_value.is_string()) {
        return prop_value;
    }
    auto prop_str = prop_value.as<std::string>();
    if (csr_utils::is_sync(prop_str)) {
        return csr_utils::replace_sync_objects(prop_str, objects_map);
    }
    if (csr_utils::is_ref(prop_str)) {
        return csr_utils::replace_ref_object(prop_str, objects_map);
    }
    if ((prop_name == PARENT_KEY || prop_name == CONTAINER_KEY) && objects_map.find(prop_str) != objects_map.end()) {
        return objects_map[prop_str];
    }
    return prop_str;
}

void rename_task::rename_management_objects(mc::dict& objects, string_map_t& objects_map) {
    objects             = replace_objects_name(objects, objects_map);
    auto replace_syntax = get_replace_syntax();
    for (auto& entry : objects) {
        if (!entry.value.is_dict()) {
            continue;
        }
        auto             obj_name = entry.key.as<std::string>();
        mc::mutable_dict props    = entry.value.as_dict();
        for (auto& child_entry : props) {
            auto prop_name = child_entry.key.as<std::string>();
            if (prop_name == BUSES_KEY) {
                auto members = child_entry.value.as<std::vector<std::string>>();
                replace_objects(members, objects_map, m_data->m_position);
                child_entry.value = members;
                continue;
            }
            auto is_numeric   = csr_utils::is_prop_type_integer(m_data->m_position, obj_name, prop_name);
            auto temp_value   = rewrite_prop_value(is_numeric, child_entry.value, replace_syntax);
            child_entry.value = rename_by_relation(prop_name, temp_value, objects_map);
        }
    }
}

void rename_task::rename_sub_prop(mc::mutable_dict& props, std::string_view sub_prop, string_map_t& objects_map) {
    if (!props.contains(sub_prop) || !props[sub_prop].is_dict()) {
        return;
    }
    auto             raw_dict = props[sub_prop].as_dict();
    mc::mutable_dict new_dict;
    for (auto& entry : raw_dict) {
        if (!entry.key.is_string()) {
            new_dict[entry.key] = entry.value;
            continue;
        }
        auto key = entry.key.as<std::string>();
        if (objects_map.find(key) != objects_map.end()) {
            new_dict[key + "_" + m_data->m_position] = entry.value;
        } else {
            new_dict[key] = entry.value;
        }
    }
    props[sub_prop] = new_dict;
}

void rename_task::rename_objects_property(mc::dict& objects, string_map_t& objects_map) {
    for (auto& entry : objects) {
        if (!entry.value.is_dict()) {
            continue;
        }
        auto obj_name   = entry.key.as<std::string>();
        auto class_name = csr_utils::get_class_name(obj_name);
        if (RENAME_PROPS.find(class_name) == RENAME_PROPS.end()) {
            continue;
        }
        mc::mutable_dict props        = entry.value.as_dict();
        auto             rename_props = RENAME_PROPS.at(class_name);
        for (auto& sub_prop : rename_props) {
            rename_sub_prop(props, sub_prop, objects_map);
        }
    }
}

void rename_task::handle_run() {
    string_map_t objects_map;
    rename_management_topology(objects_map);
    if (!m_data->m_objects.has_value()) {
        return;
    }
    auto& csr_objects = m_data->m_objects.value();
    rename_management_objects(csr_objects, objects_map);
    rename_objects_property(csr_objects, objects_map);
    m_data->m_sdr_data[OBJECTS_KEY] = csr_objects;
}

append_task::append_task(raw_data_t* data, std::string_view name) : parse_task(data, name) {
}

static string_map_t get_connector_parent(mc::dict& topology) {
    string_map_t parent_map;
    for (auto& entry : topology) {
        if (!entry.value.is_dict()) {
            continue;
        }
        auto parent_name = entry.key.as<std::string>();
        auto members     = entry.value.as_dict();
        for (auto& child_entry : members) {
            if (!child_entry.value.is_array() || child_entry.key != CONNECTORS_KEY) {
                continue;
            }
            auto connectors = child_entry.value.as<std::vector<std::string>>();
            for (auto& connector : connectors) {
                parent_map[connector] = parent_name;
            }
        }
    }
    return parent_map;
}

std::string append_task::get_e2p_name_by_props(mc::dict& props) {
    mc::variant connector_position = 0;
    if (props.contains(POSITION_KEY)) {
        connector_position = props[POSITION_KEY];
        if (connector_position.is_double()) {
            connector_position = static_cast<int>(std::floor(connector_position.as<double>()));
        }
    }
    return "Eeprom_" + std::to_string(COMPONENT_E2P) + "_" + connector_position.as_string() + "_" +
           std::string(m_data->m_position);
}

void append_task::proprocess_connectors(mc::mutable_dict& objects) {
    for (auto& entry : objects) {
        auto object_name = entry.key.as_string();
        if (csr_utils::get_class_name(object_name) != "Connector" || !entry.value.is_dict()) {
            continue;
        }
        mc::mutable_dict props         = entry.value.as_dict();
        props["SystemId"]              = props.get("SystemId", 1).as_string();
        uint64_t    connector_position = props.get(POSITION_KEY, 1).as_uint64();
        std::string group_position     = std::string(m_data->m_position) + mc::format_v("%02X", connector_position);
        props["GroupPosition"]         = group_position;
        props["GroupId"]               = get_group_id(group_position);
    }
}

void append_task::handle_run() {
    if (!m_data->m_management_topology.has_value() || !m_data->m_objects.has_value()) {
        return;
    }
    auto& topology         = m_data->m_management_topology.value();
    auto& objects          = m_data->m_objects.value();
    auto  connector_parent = get_connector_parent(topology);
    for (auto& [connector, bus_name] : connector_parent) {
        if (!objects.contains(connector) || !objects[connector].is_dict()) {
            continue;
        }
        mc::mutable_dict connector_props = objects[connector].as_dict();
        if (!connector_props.contains(IDENTIFY_MODE_KEY) || !connector_props[IDENTIFY_MODE_KEY].is_integer()) {
            continue;
        }
        int identify_mode = connector_props[IDENTIFY_MODE_KEY].as<int>();
        if (identify_mode != COMPONENT_E2P) {
            continue;
        }
        // 对于天池标准组件添加Eeprom及引用
        auto e2p_name = get_e2p_name_by_props(connector_props);
        // 自定义Chip属性添加对象引用关系
        connector_props["Id"]         = "";
        connector_props["Chip"]       = std::string(REF_TAG) + e2p_name;
        connector_props["CSRVersion"] = std::string(REF_TAG) + e2p_name + ".CSRVersion";
        // 拓扑结构下添加Chips
        mc::mutable_dict         bus_topology = topology[bus_name].as_dict();
        std::vector<std::string> chips;
        if (bus_topology.contains(CHIPS_KEY)) {
            chips = bus_topology[CHIPS_KEY].as<std::vector<std::string>>();
        }
        chips.push_back(e2p_name);
        bus_topology[CHIPS_KEY] = chips;
        // 对象结构下添加Eeprom
        mc::variant chip_addr = 0xae;
        if (connector_props.contains("IdChipAddr") && connector_props["IdChipAddr"] != 0) {
            chip_addr = connector_props["IdChipAddr"];
        }
        mc::dict e2p_object({{"OffsetWidth", 2},
                             {"AddrWidth", 1},
                             {"Address", chip_addr},
                             {"ReadTmout", 100},
                             {"WriteTmout", 100},
                             {"RwBlockSize", 32},
                             {"WriteInterval", 20}});
        objects[e2p_name] = e2p_object;
    }
    proprocess_connectors(objects);
    object_group_data::get_instance().save_topology(m_data->m_position, csr_utils::convert_topology(topology));
}

arrange_task::arrange_task(raw_data_t* data, std::string_view name) : parse_task(data, name) {
}

static void parse_object_ref(std::string object_name, std::string ref_object, objs_ref_info& info,
                             const mc::dict& objects) {
    if (!objects.contains(ref_object) || ref_object == object_name) {
        return;
    }
    info.ref_objects[ref_object].push_back(object_name);
    info.ref_count[object_name]++;
}

static void parse_ref_object_count(const mc::dict::entry& entry, objs_ref_info& info, const mc::dict& objects) {
    auto object_name = entry.key.as<std::string>();
    auto props       = entry.value.as_dict();
    bool has_parent  = false;
    for (auto& prop : props) {
        if (!prop.value.is_string()) {
            continue;
        }
        auto prop_name  = prop.key.as<std::string>();
        auto prop_value = prop.value.as<std::string>();
        if (csr_utils::is_ref(prop_value)) {
            for (auto& target : csr_utils::get_ref_targets(prop_value)) {
                parse_object_ref(object_name, target.object_name, info, objects);
            }
        } else if (prop_name == PARENT_KEY) {
            if (has_parent) {
                MC_THROW(mc::parse_error_exception, "multiple parent found for object: ${object}",
                         ("object", object_name));
            }
            has_parent = true;
            parse_object_ref(object_name, prop_value, info, objects);
        }
    }
}

objs_ref_info arrange_task::get_ref_obj_count(const mc::dict& objects) {
    objs_ref_info info;
    for (auto& entry : objects) {
        if (!entry.value.is_dict()) {
            continue;
        }
        info.objects_count++;
        parse_ref_object_count(entry, info, objects);
    }
    return info;
}

static std::vector<std::string> arrange_objects_queue(std::unordered_set<std::string>& object_names,
                                                      objs_ref_info&                   info) {
    std::vector<std::string>                objects_queue;
    std::unordered_map<std::string, size_t> objects_index;
    while (objects_queue.size() < info.objects_count) {
        size_t sorted_count = objects_queue.size();
        for (auto& object_name : object_names) {
            if (objects_index.find(object_name) != objects_index.end()) {
                continue;
            }
            if (info.ref_count[object_name] > 0) {
                continue;
            }
            objects_index[object_name] = objects_queue.size();
            objects_queue.push_back(object_name);
            if (info.ref_objects.find(object_name) == info.ref_objects.end()) {
                continue;
            }
            for (auto& ref_object : info.ref_objects[object_name]) {
                info.ref_count[ref_object]--;
            }
            info.ref_objects.erase(object_name);
        }
        if (sorted_count == objects_queue.size()) {
            MC_THROW(mc::parse_error_exception, "circular reference found in objects");
        }
    }
    return objects_queue;
}

static void parse_sync_object_prop_count(std::string object_name, const mc::dict::entry& prop_entry,
                                         objs_ref_info& info, mc::dict& objects) {
    if (!prop_entry.value.is_string()) {
        return;
    }
    auto                         prop_name         = prop_entry.key.as<std::string>();
    auto                         prop_value        = prop_entry.value.as<std::string>();
    std::string                  local_object_prop = object_name + "." + prop_name;
    std::vector<ref_sync_target> targets;
    if (csr_utils::is_sync(prop_value)) {
        targets = csr_utils::get_sync_targets(prop_value);
    } else if (csr_utils::is_ref(prop_value)) {
        targets = csr_utils::get_ref_targets(prop_value);
    } else {
        return;
    }
    for (auto& target : targets) {
        if (target.object_name == object_name && target.prop_name == prop_name) {
            MC_THROW(mc::parse_error_exception,
                     "self reference found in object: ${object}, property: ${property}, value: ${value}",
                     ("object", object_name)("property", prop_name)("value", prop_value));
        }
        if (!objects.contains(target.object_name) || target.is_global) {
            continue;
        }
        std::string target_object_prop = target.object_name + "." + target.prop_name;
        info.ref_objects[target_object_prop].push_back(local_object_prop);
        info.ref_count[local_object_prop]++;
    }
}

static objs_ref_info get_sync_obj_prop_count(mc::dict& objects, std::unordered_set<std::string>& sync_objects) {
    objs_ref_info info;
    for (auto& entry : objects) {
        if (!entry.value.is_dict()) {
            continue;
        }
        auto object_name = entry.key.as<std::string>();
        auto props       = entry.value.as_dict();
        for (auto& prop_entry : props) {
            parse_sync_object_prop_count(object_name, prop_entry, info, objects);
        }
    }
    for (auto& [ref_target, object_props] : info.ref_objects) {
        if (sync_objects.find(ref_target) == sync_objects.end()) {
            sync_objects.insert(ref_target);
            info.objects_count++;
        }
        for (auto& prop : object_props) {
            if (sync_objects.find(prop) == sync_objects.end()) {
                sync_objects.insert(prop);
                info.objects_count++;
            }
        }
    }
    return info;
}

void arrange_task::handle_run() {
    if (!m_data->m_objects.has_value()) {
        return;
    }
    auto&                           objects = m_data->m_objects.value();
    auto                            result  = get_ref_obj_count(objects);
    std::unordered_set<std::string> object_names;
    for (auto& entry : objects) {
        auto obj_name = entry.key.as<std::string>();
        object_names.insert(obj_name);
    }
    m_data->m_objects_queue = arrange_objects_queue(object_names, result);
    std::unordered_set<std::string> sync_objects;
    result = get_sync_obj_prop_count(objects, sync_objects);
    arrange_objects_queue(sync_objects, result);
}

analyze_task::analyze_task(raw_data_t* data, std::string_view name) : parse_task(data, name) {
}

static mc::mutable_dict make_variable_map(mc::dict& context, std::string_view object_name) {
    mc::mutable_dict variable_map;
    if (context.contains(SYSTEM_ID_KEY)) {
        variable_map[SYSTEM_ID_KEY] = context[SYSTEM_ID_KEY];
    }
    if (context.contains(MANAGER_ID_KEY)) {
        variable_map[MANAGER_ID_KEY] = context[MANAGER_ID_KEY];
    }
    if (context.contains(CHASSIS_ID_KEY)) {
        variable_map[CHASSIS_ID_KEY] = context[CHASSIS_ID_KEY];
    }
    
    // 对象ID使用完整的对象名
    variable_map[ID_KEY] = object_name;
    return variable_map;
}

void analyze_task::pre_parse_objects(
    mc::mutable_dict& objects, std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::vector<std::string>>& object_children) {
    for (auto& object_name : m_data->m_objects_queue) {
        if (object_name.substr(0, 5) == "Func_") {
            continue;
        }
        mc::mutable_dict props        = objects[object_name].as_dict();
        auto             variable_map = make_variable_map(m_data->m_context, object_name);
        std::string      parent_path;
        std::string      parent_name;
        if (props.contains(PARENT_KEY) && props[PARENT_KEY].is_string()) {
            parent_name = props[PARENT_KEY].as<std::string>();
            if (object_info.find(parent_name) == object_info.end()) {
                wlog("parent object not found, object: ${object}, parent: ${parent}",
                     ("object", object_name)("parent", parent_name));
                continue;
            }
            auto parent_info = object_info[parent_name];
            if (parent_info.path.empty()) {
                wlog("parent object path is empty, object: ${object}, parent: ${parent}",
                     ("object", object_name)("parent", parent_name));
                continue;
            }
            parent_path            = parent_info.path;
            variable_map["Parent"] = parent_path;
        }
        instance_info_t instance_info =
            csr_utils::get_instance_info(m_data->m_position, object_name, variable_map);
        if (instance_info.app.empty() || (!parent_path.empty() && instance_info.path.empty())) {
            wlog("get class info failed, object: ${object}", ("object", object_name));
            continue;
        }
        if (!parent_path.empty()) {
            instance_info.parent = parent_path;
            object_children[parent_name].push_back(instance_info.path);
            props[PARENT_KEY] = parent_path;
        }
        instance_info.object_name = object_name;
        object_info[object_name]  = instance_info;
    }
}

static std::shared_ptr<parsed_sr_object> new_object(std::string object_name, std::string class_name,
                                                    mc::mutable_dict& props, instance_info_t& instance_info,
                                                    mc::dict& context) {
    auto object          = std::make_shared<parsed_sr_object>();
    object->object_name  = object_name;
    object->class_name   = class_name;
    object->app_name     = instance_info.app;
    object->path         = instance_info.path;
    object->object_props = props;
    object->ref_presence = instance_info.ref_presence;
    if (!instance_info.path.empty()) {
        object->extra_props["Path"] = instance_info.path;
    }
    if (!instance_info.parent.empty()) {
        object->extra_props[PARENT_KEY] = instance_info.parent;
    }
    if (context.contains("Bom")) {
        object->extra_props["Bom"] = context["Bom"];
    }
    if (context.contains("Id")) {
        object->extra_props["BoardId"] = context["Id"];
    }
    if (context.contains("AuxId")) {
        object->extra_props["AuxId"] = context["AuxId"];
    }
    return object;
}

static std::shared_ptr<parsed_sr_func_object> new_func_object(std::string object_name, std::string class_name,
                                                    mc::mutable_dict& props, std::vector<std::string>& app_names) {
    auto object          = std::make_shared<parsed_sr_func_object>();
    object->object_name  = object_name;
    object->class_name   = class_name;
    object->app_names = app_names;
    object->object_props = props;
    return object;
}

static std::string generate_expr_str(std::string prop_value) {
    auto expr_list = csr_utils::get_prop_expr(prop_value, MAX_EXPR_LEVEL);
    if (expr_list.empty()) {
        return "";
    }
    auto exprs = mc::string::join(expr_list, ", ");
    return mc::format_dict(R"(,"expressions":[${exprs}])", mc::mutable_dict()("exprs", exprs));
}

static std::string generate_default_str(const mc::variant& default_value) {
    if (default_value.is_null()) {
        return "";
    }
    return mc::format_dict(R"(,"Default":${value})", mc::mutable_dict()("value", default_value.to_string()));
}

static std::optional<std::string> make_ref_url(std::unordered_map<std::string, instance_info_t>& object_info,
                                               std::string prop_value, instance_info_t& instance_info,
                                               std::string position) {
    auto targets = csr_utils::get_ref_targets(prop_value);
    if (targets.empty()) {
        return prop_value;
    }
    auto target = targets[0];
    instance_info.references.push_back(target.object_name);
    std::string expr = generate_expr_str(prop_value);
    if (instance_info.object_name == target.object_name) {
        if (target.prop_name.empty()) {
            wlog("get reference object property failed, object: ${object}", ("object", instance_info.object_name));
            return std::nullopt;
        }
        return mc::format_dict(
            R"($local:{{"properties":[{{"ObjectName":"${object}","Property":"${property}"}}]${expr}}})",
            mc::mutable_dict()("object", target.object_name)("property", target.prop_name)("expr", expr));
    }
    if (object_info.find(target.object_name) == object_info.end()) {
        wlog("reference object not found, object: ${object}", ("object", target.object_name));
        return std::nullopt;
    }
    auto target_object_info = object_info[target.object_name];
    if (target_object_info.app == instance_info.app && !target.is_global) {
        // 对于函数对象，强制使用完整的$ref格式，不进行简化
        auto func_class_name = csr_utils::get_class_name(instance_info.object_name);
        if (func_class_name != "Func") {
            return prop_value.substr(2);  // 去掉 "#/" 前缀，返回简化格式
        }
    }
    if (target_object_info.path.empty()) {
        wlog("reference object path is empty, object: ${object}", ("object", target.object_name));
        return std::nullopt;
    }
    if (target.prop_name.empty()) {
        return mc::format_dict(R"($ref:{{"Service":"bmc.kepler.${app}","Path":"${path}"}})",
                               mc::mutable_dict()("app", target_object_info.app)("path", target_object_info.path));
    }
    auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
    if (property_intf.empty()) {
        return std::nullopt;
    }
    return mc::format_dict(
        R"($ref:{{"properties":[{{"Service":"bmc.kepler.${app}","Path":"${path}","Interface":"${intf}","Property":"${property}"}}]${expr}}})",
        mc::mutable_dict()("app", target_object_info.app)("path", target_object_info.path)("intf", property_intf)(
            "property", property_name)("expr", expr));
}

static std::optional<std::string> make_sync_url(std::unordered_map<std::string, instance_info_t>& object_info,
                                                std::string prop_value, instance_info_t& instance_info,
                                                const mc::variant& default_value, std::string position) {
    auto targets = csr_utils::get_sync_targets(prop_value);
    if (targets.size() > 10) {
        MC_THROW(mc::parse_error_exception, "number of sync properties exceeds limit, object: ${object}",
                 ("object", instance_info.object_name));
    }
    std::vector<std::string> properties;
    for (auto& target : targets) {
        instance_info.references.push_back(target.object_name);
        if (object_info.find(target.object_name) == object_info.end() || object_info[target.object_name].path.empty()) {
            wlog("get sync object path failed, object: ${object}", ("object", target.object_name));
            return std::nullopt;
        }
        auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
        if (property_intf.empty()) {
            return std::nullopt;
        }
        auto target_object_info = object_info[target.object_name];
        properties.push_back(mc::format_dict(
            R"({{"Service":"bmc.kepler.${app}","Path":"${path}","Interface":"${intf}","Property":"${property}"}})",
            mc::mutable_dict()("app", target_object_info.app)("path", target_object_info.path)("intf", property_intf)(
                "property", property_name)));
    }
    std::string expr        = generate_expr_str(prop_value);
    std::string default_str = generate_default_str(default_value);
    auto        props_str   = mc::string::join(properties, ",");
    return mc::format_dict(R"($sync:{{"properties":[${props}]${expr}${default}}})",
                           mc::mutable_dict()("props", props_str)("expr", expr)("default", default_str));
}

static std::optional<std::string> make_expr_url(std::string prop_value) {
    std::regex  pattern(R"(^\s*(.*?)\s*\|>)");
    std::smatch match;
    if (std::regex_search(prop_value, match, pattern)) {
        auto param = match[1].str();
        auto expr  = generate_expr_str(prop_value);
        return mc::format_dict(R"($const:{{"properties":[${param}]${expr}}})",
                               mc::mutable_dict()("param", param)("expr", expr));
    }
    return std::nullopt;
}

// 处理属性引用
static std::optional<std::string>
make_relate_property_url(std::unordered_map<std::string, instance_info_t>& object_info, instance_info_t& instance_info,
                         const mc::variant& prop_value, const std::string_view& position) {
    std::string object_name   = prop_value["object_name"].as<std::string>() + "_" + std::string(position);
    std::string interface     = prop_value["interface"].as<std::string>();
    std::string property_name = prop_value["property_name"].as<std::string>();
    std::string type          = prop_value["type"].as<std::string>();

    // 检查对象是否存在于 object_info 中
    if (object_info.find(object_name) == object_info.end()) {
        wlog("get relate object path failed, object: ${object} (not found in object_info)", ("object", object_name));
        return std::nullopt;
    }
    if (object_info[object_name].path.empty()) {
        wlog("get relate object path failed, object: ${object} (path is empty)", ("object", object_name));
        return std::nullopt;
    }

    if (interface.empty()) {
        // 获取属性接口信息
        auto [intf, prop] = csr_utils::get_property_intf(std::string(position), std::string(object_name), std::string(property_name));
        interface = intf;
        if (interface.empty()) {
            return std::nullopt;
        }
    }

    auto target_object_info = object_info[object_name];
    if (type == "ref" && instance_info.app == target_object_info.app) {
        return mc::format_dict(R"($local:{{"ObjectName":"${object}","Property":"${property}"}})",
                               mc::mutable_dict()("object", object_name)("property", property_name));
    }

    auto prefix = type == "sync" ? "$sync:" : "$ref:";
    mc::mutable_dict args;
    args["prefix"] = prefix;
    args["app"] = target_object_info.app;
    args["path"] = target_object_info.path;
    args["intf"] = interface;
    args["property"] = property_name;
    return mc::format_dict(
        R"(${prefix}{{"Service":"bmc.kepler.${app}","Path":"${path}","Interface":"${intf}","Property":"${property}"}})",
        args);
}

static std::optional<std::string> make_func_info_url(std::unordered_map<std::string, instance_info_t>& object_info,
                                                     instance_info_t& instance_info, func_call& func_info,
                                                     const std::string_view& position) {
    mc::mutable_dict params_dict;
    for (auto it = func_info.params.begin(); it != func_info.params.end(); ++it) {
        std::string param_value;
        if (is_function_call(it->value)) {
            // 递归处理嵌套的函数调用
            auto nested_func_info = it->value.as<func_call>();
            auto nested_result    = make_func_info_url(object_info, instance_info, nested_func_info, position);
            param_value           = nested_result.has_value() ? nested_result.value() : it->value.to_string();
        } else if (is_relate_property(it->value)) {
            // 处理 relate 属性，转换为 Service、Path、Interface、Property 格式
            auto relate_url = make_relate_property_url(object_info, instance_info, it->value, position);
            // 提取前缀后面的 JSON 部分
            param_value = relate_url.has_value() ? relate_url.value() : it->value.to_string();
        } else {
            param_value = it->value.to_string();
        }
        params_dict[it->key] = param_value;
    }

    // 构建最终的 JSON 字符串
    std::string params_json = params_dict.to_string();
    mc::mutable_dict args;
    args["func"] = func_info.func;
    args["params"] = params_json;
    return mc::format_dict(R"($func:{{"func":"${func}","params":${params}}})", args);
}

static std::optional<std::string> make_func_call_url(std::unordered_map<std::string, instance_info_t>& object_info,
                                                     std::string prop_value, instance_info_t& instance_info,
                                                     std::string position) {
    auto func_info = func_parser::get_instance().parse_function_call(prop_value);
    if (func_info.func.empty()) {
        return prop_value;
    }

    return make_func_info_url(object_info, instance_info, func_info, position);
}

// 抽取函数依赖分析的公共逻辑
static std::set<std::string> extract_function_dependencies(const std::string& prop_value) {
    std::set<std::string> func_deps;
    std::regex func_pattern(R"(\$Func_([a-zA-Z_]\w*)\()");
    std::sregex_iterator iter(prop_value.begin(), prop_value.end(), func_pattern);
    std::sregex_iterator end;
    
    while (iter != end) {
        std::string func_name = "Func_" + iter->str(1);
        func_deps.insert(func_name);
        ++iter;
    }
    
    if (!func_deps.empty()) {
        wlog("total ${count} function dependencies extracted from: ${value}", 
             ("count", func_deps.size())("value", prop_value));
    }
    
    return func_deps;
}

// 从完整的函数对象名称中提取基础函数名（去掉位置后缀）
static std::string extract_base_func_name(const std::string& func_object_name) {
    // 函数对象名格式：Func_calculate_port_count_1A
    // 需要提取：Func_calculate_port_count
    auto last_underscore = func_object_name.find_last_of('_');
    if (last_underscore != std::string::npos && last_underscore > 5) { // 确保不是Func_部分的下划线
        return func_object_name.substr(0, last_underscore);
    }
    return func_object_name;
}

// 为函数对象参数创建简化的引用URL
static std::optional<std::string> make_simple_ref_url(
    std::unordered_map<std::string, instance_info_t>& object_info,
    const std::string& prop_value, 
    instance_info_t& instance_info,
    const std::string& position) {
    
    auto targets = csr_utils::get_ref_targets(prop_value);
    if (targets.size() != 1) {
        // 如果不是单一引用，回退到标准格式
        return make_ref_url(object_info, prop_value, instance_info, position);
    }
    
    auto& target = targets[0];
    if (object_info.find(target.object_name) == object_info.end()) {
    return std::nullopt;
}

    auto target_object_info = object_info[target.object_name];
    auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
    if (property_intf.empty()) {
        return std::nullopt;
    }
    
    if (instance_info.app == target_object_info.app) {
        return mc::format_dict(R"($local:{{"ObjectName":"${object}","Property":"${property}"}})",
                               mc::mutable_dict()("object", target.object_name)("property", property_name));
    }

    // 返回简化的单一对象格式
    return mc::format_dict(
        R"($ref:{{"Service":"bmc.kepler.${app}","Path":"${path}","Interface":"${intf}","Property":"${property}"}})",
        mc::mutable_dict()("app", target_object_info.app)("path", target_object_info.path)
                          ("intf", property_intf)("property", property_name));
}

// 为函数对象参数创建简化的同步URL
static std::optional<std::string> make_simple_sync_url(
    std::unordered_map<std::string, instance_info_t>& object_info,
    const std::string& prop_value,
    instance_info_t& instance_info,
    const std::string& position) {
    
    auto targets = csr_utils::get_sync_targets(prop_value);
    if (targets.size() != 1) {
        // 如果不是单一同步，回退到标准格式
        return make_sync_url(object_info, prop_value, instance_info, mc::variant(), position);
    }
    
    auto& target = targets[0];
    if (object_info.find(target.object_name) == object_info.end()) {
        return std::nullopt;
    }
    
    auto target_object_info = object_info[target.object_name];
    auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
    if (property_intf.empty()) {
        return std::nullopt;
    }
    
    // 返回简化的单一对象格式
    return mc::format_dict(
        R"($sync:{{"Service":"bmc.kepler.${app}","Path":"${path}","Interface":"${intf}","Property":"${property}"}})",
        mc::mutable_dict()("app", target_object_info.app)("path", target_object_info.path)
                          ("intf", property_intf)("property", property_name));
}

// 处理引用格式的字符串值
static std::optional<std::string> process_ref_string_value(
    const std::string& prop_value,
    const std::string& position,
    std::unordered_map<std::string, instance_info_t>& object_info,
    instance_info_t& instance_info) {
    
    if (!csr_utils::is_ref(prop_value)) {
        return std::nullopt;
    }
    
    // 解析引用格式并在对象名后加上位置后缀
    std::string processed_prop_value = prop_value;
    std::regex ref_pattern(R"(#/([^./]+)(\.|$))");
    std::smatch match;
    if (std::regex_search(prop_value, match, ref_pattern)) {
        std::string object_name = match[1].str();
        std::string suffix = match[2].str();
        std::string old_ref = "#/" + object_name + suffix;
        std::string new_ref = "#/" + object_name + "_" + position + suffix;
        processed_prop_value = mc::string::replace_all(processed_prop_value, old_ref, new_ref);
    }
    
    return make_simple_ref_url(object_info, processed_prop_value, instance_info, position);
}

// 处理同步格式的字符串值
static std::optional<std::string> process_sync_string_value(
    const std::string& prop_value,
    const std::string& position,
    std::unordered_map<std::string, instance_info_t>& object_info,
    instance_info_t& instance_info) {
    
    if (!csr_utils::is_sync(prop_value)) {
        return std::nullopt;
    }
    
    // 解析同步格式并在对象名后加上位置后缀
    std::string processed_prop_value = prop_value;
    std::regex sync_pattern(R"(<=/([^./]+)\.)");
    std::smatch match;
    if (std::regex_search(prop_value, match, sync_pattern)) {
        std::string object_name = match[1].str();
        std::string old_sync = "<=/" + object_name + ".";
        std::string new_sync = "<=/" + object_name + "_" + position + ".";
        processed_prop_value = mc::string::replace_all(processed_prop_value, old_sync, new_sync);
    }
    
    return make_simple_sync_url(object_info, processed_prop_value, instance_info, position);
}

// 处理单个字符串值
static std::optional<std::string> process_string_value(
    const std::string& prop_value,
    const std::string& position,
    std::unordered_map<std::string, instance_info_t>& object_info,
    instance_info_t& instance_info,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps) {
    
    // 检查属性值中是否包含函数调用，提取函数依赖
    auto func_deps = extract_function_dependencies(prop_value);
    for (const auto& func_name : func_deps) {
        func_to_apps[func_name].insert(instance_info.app);
    }
    
    // 尝试处理引用格式
    auto ref_result = process_ref_string_value(prop_value, position, object_info, instance_info);
    if (ref_result.has_value()) {
        return ref_result;
    }
    
    // 尝试处理同步格式
    auto sync_result = process_sync_string_value(prop_value, position, object_info, instance_info);
    if (sync_result.has_value()) {
        return sync_result;
    }
    
    // 如果没有特殊格式，返回原值
    return prop_value;
}

// 递归处理嵌套的dict中的属性值
static void process_nested_dict_properties(
    mc::mutable_dict& nested_dict,
    const std::string& object_name,
    instance_info_t& instance_info,
    std::unordered_map<std::string, instance_info_t>& object_info,
    const std::string& position,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps) {
    
    for (auto& entry : nested_dict) {
        auto key_str = entry.key.as_string();
        
        if (entry.value.is_string()) {
            auto prop_value = entry.value.as<std::string>();
            auto new_value = process_string_value(prop_value, position, object_info, instance_info, func_to_apps);
            
            if (new_value.has_value() && new_value.value() != prop_value) {
                nested_dict[entry.key] = new_value.value();
            }
        } else if (entry.value.is_dict()) {
            // 递归处理嵌套的dict
            auto nested_mutable = entry.value.as_dict().as_mut();
            process_nested_dict_properties(nested_mutable, object_name, instance_info, object_info, position, func_to_apps);
            nested_dict[entry.key] = nested_mutable;
        }
    }
}

static void set_device_obj_ref_info(mc::engine::abstract_object* device_object,
                                    instance_info_t&                                  instance_info,
                                    std::unordered_map<std::string, instance_info_t>& object_info,
                                    const std::string& position, const std::string& prop_value,
                                    std::string_view prop_name, std::string_view intf_name) {
    auto targets = csr_utils::get_ref_targets(prop_value);
    if (targets.empty()) {
        return;
    }
    auto        target      = targets[0];
    std::string object_name = target.object_name + "_" + position;
    if (object_info.find(object_name) == object_info.end()) {
        wlog("reference object not found, object: ${object}", ("object", object_name));
        return;
    }
    std::string expr               = generate_expr_str(prop_value);
    auto        target_object_info = object_info[object_name];
    if (target_object_info.app != instance_info.app) {
        if (target_object_info.path.empty()) {
            wlog("reference object path is empty, object: ${object}", ("object", object_name));
            return;
        }
        if (target.prop_name.empty()) {
            std::string ref_info = csr_utils::get_remote_ref_object_info(target_object_info.app,
                                                                         target_object_info.path);
            device_object->set_property_ref_info(prop_name, ref_info, intf_name);
            return;
        }
        auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
        std::string ref_info                = csr_utils::get_remote_ref_property_info(
            target_object_info.app, target_object_info.path, property_intf, property_name, expr);
        device_object->set_property_ref_info(prop_name, ref_info, intf_name);
        return;
    }
    if (!target.prop_name.empty()) {
        std::string ref_info =
            csr_utils::get_local_ref_property_info(object_name, target.prop_name, expr);
        device_object->set_property_ref_info(prop_name, ref_info, intf_name);
        return;
    }
    if (instance_info.object_name == object_name) {
        wlog("invalid object self reference: ${object}", ("object", instance_info.object_name));
        return;
    }
    std::string ref_info = csr_utils::get_local_ref_object_info(object_name);
    device_object->set_property_ref_info(prop_name, ref_info, intf_name);
}

static void set_device_obj_sync_info(mc::engine::abstract_object* device_object,
                                     instance_info_t&             instance_info,
                                     std::unordered_map<std::string, instance_info_t>& object_info,
                                     const mc::variant& default_value, const std::string& position,
                                     const std::string& prop_value, std::string_view prop_name,
                                     std::string_view intf_name) {
    auto targets = csr_utils::get_sync_targets(prop_value);
    if (targets.size() > 10) {
        MC_THROW(mc::parse_error_exception,
                 "number of sync properties exceeds limit, object: ${object}",
                 ("object", instance_info.object_name));
    }
    auto sync_info = std::make_shared<mc::engine::property_sync_info>();
    for (auto& target : targets) {
        std::string object_name = target.object_name + "_" + position;
        if (object_info.find(object_name) == object_info.end() ||
            object_info[object_name].path.empty()) {
            wlog("get sync object path failed, object: ${object}", ("object", object_name));
            return;
        }
        auto [property_intf, property_name] = csr_utils::get_property_intf(position, target);
        auto target_object_info             = object_info[object_name];
        sync_info->properties.emplace_back("bmc.kepler." + target_object_info.app,
                                           target_object_info.path, property_intf, property_name);
    }
    std::string expr        = generate_expr_str(prop_value);
    std::string default_str = generate_default_str(default_value);
    sync_info->source = csr_utils::get_sync_property_info(expr, default_str, sync_info->properties);
    device_object->set_property_sync_info(prop_name, std::move(sync_info), intf_name);
}

static void
parse_device_obj_ref_sync_info(const std::string& object_name, std::string_view intf_name,
                               const mc::dict& intf_data, instance_info_t& instance_info,
                               std::unordered_map<std::string, instance_info_t>& object_info,
                               const std::string&                                position) {
    auto* device_object = devmon::object_group_data::get_instance().get_device_object(position, object_name);
    if (!device_object) {
        wlog("device object ${object_name} not found, position: ${position}", ("object_name", object_name)("position", position));
        return;
    }
    if (!device_object->has_interface(intf_name)) {
        wlog("device interface ${intf_name} not found, position: ${position}, object: ${object_name}",
             ("intf_name", intf_name)("position", position)("object_name", object_name));
        return;
    }
    mc::dict default_values;
    if (intf_data.contains(DEFAULT_KEY) && intf_data[DEFAULT_KEY].is_dict()) {
        default_values = intf_data[DEFAULT_KEY].as_dict();
    }
    for (auto& entry : intf_data) {
        if (!entry.value.is_string()) {
            continue;
        }
        auto prop_name = entry.key.as_string();
        auto prop_value = entry.value.as_string();
        if (csr_utils::is_ref(prop_value)) {
            set_device_obj_ref_info(device_object, instance_info, object_info, position, prop_value,
                                    prop_name, intf_name);
        } else if (csr_utils::is_sync(prop_value)) {
            auto default_value = default_values.get(prop_name, mc::variant());
            set_device_obj_sync_info(device_object, instance_info, object_info, default_value,
                                     position, prop_value, prop_name, intf_name);
        }
    }
}

// 公共的属性解析函数
static std::vector<std::string> parse_object_properties(
    mc::mutable_dict& props, 
    const std::string& object_name,
    const std::string& class_name,
    instance_info_t& instance_info,
    const mc::dict& default_values,
    std::unordered_map<std::string, instance_info_t>& object_info,
    const std::string& position,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps) {
    std::vector<std::string> failed_props;
    for (auto& prop_entry : props) {
        auto prop_name = prop_entry.key.as<std::string>();
        
        if (prop_entry.value.is_string()) {
            auto prop_value = prop_entry.value.as<std::string>();
            
            // 检查属性值中是否包含函数调用，提取函数依赖
            auto func_deps = extract_function_dependencies(prop_value);
            for (const auto& func_name : func_deps) {
                func_to_apps[func_name].insert(instance_info.app);
            }
            
            std::optional<std::string> new_value = prop_value;
            if (csr_utils::is_ref(prop_value)) {
                new_value = make_ref_url(object_info, prop_value, instance_info, position);
            } else if (csr_utils::is_sync(prop_value)) {
                new_value = make_sync_url(object_info, prop_value, instance_info,
                                          default_values.get(prop_name, mc::variant()), position);
            } else if (prop_value.find(EXPR_TAG) != std::string::npos) {
                new_value = make_expr_url(prop_value);
            } else if (csr_utils::is_func_call(prop_value)) {
                new_value = make_func_call_url(object_info, prop_value, instance_info, position);
            }
            
            if (new_value.has_value()) {
                props[prop_name] = new_value.value();
            } else {
                failed_props.push_back(prop_name);
            }
            
            if (csr_utils::is_ref_presence(prop_value, class_name, prop_name)) {
                instance_info.ref_presence = true;
            }
            continue;
        } else if (!prop_entry.value.is_dict()) {
            continue;
        }
        auto prop_value = prop_entry.value.as_dict();
        if (class_name == "Func") {
            // 处理嵌套的dict（比如函数对象的args）
            auto nested_dict = prop_value.as_mut();
            process_nested_dict_properties(nested_dict, object_name, instance_info, object_info, position, func_to_apps);
            props[prop_name] = nested_dict;
        } else if (mc::string::starts_with(prop_name, "bmc.dev")) {
            parse_device_obj_ref_sync_info(object_name, prop_name, prop_value, instance_info,
                                           object_info, position);
        }
    }
    
    return failed_props;
}

// 处理单个普通对象
bool analyze_task::process_single_regular_object(
    const std::string& object_name,
    mc::mutable_dict& objects,
    std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps,
    std::vector<std::shared_ptr<parsed_sr_object>>& parsed_objects,
    std::unordered_map<std::string, std::shared_ptr<parsed_sr_object>>& object_index) {
    
    if (object_info.find(object_name) == object_info.end()) {
        return false;
    }
    
    auto class_name = csr_utils::get_class_name(object_name);
    mc::mutable_dict props = objects[object_name].as_dict();
    mc::dict default_values;
    if (props.contains(DEFAULT_KEY) && props[DEFAULT_KEY].is_dict()) {
        default_values = props[DEFAULT_KEY].as_dict();
    }
    props.erase(DEFAULT_KEY);
    auto instance_info = object_info[object_name];
    
    // 使用公共属性解析函数
    auto failed_props = parse_object_properties(props, object_name, class_name, instance_info, 
                                               default_values, object_info, m_data->m_position, func_to_apps);
    
        for (auto& prop_name : failed_props) {
            props.erase(prop_name);
        }
        auto parsed_object_ptr = new_object(object_name, class_name, props, instance_info, m_data->m_context);
        parsed_objects.push_back(parsed_object_ptr);
        object_index[object_name] = parsed_object_ptr;
    return true;
}

// 为单个应用处理单个函数对象
void analyze_task::process_single_function_object_for_app(
    const std::string& func_object_name,
    const std::string& app_name,
    mc::mutable_dict& func_props,
    std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps,
    std::vector<std::shared_ptr<parsed_sr_func_object>>& parsed_func_objects) {
    
    // 创建针对该应用的instance_info
    instance_info_t func_instance_info;
    func_instance_info.app = app_name;
    func_instance_info.object_name = func_object_name;
    
    // 复制属性进行单独解析
    mc::mutable_dict app_func_props = func_props;
    mc::dict empty_defaults;
    
    // 解析函数对象的属性，可能包含嵌套的函数依赖
    auto failed_props = parse_object_properties(app_func_props, func_object_name, csr_utils::get_class_name(func_object_name), 
                                               func_instance_info, empty_defaults, object_info, 
                                               m_data->m_position, func_to_apps);
    
    for (auto& prop_name : failed_props) {
        app_func_props.erase(prop_name);
    }
    
    // 为该应用创建函数对象，保持原始名称（包含位置后缀）
    std::vector<std::string> single_app = {app_name};
    auto func_parsed_object = new_func_object(func_object_name, csr_utils::get_class_name(func_object_name), app_func_props, single_app);
    parsed_func_objects.push_back(func_parsed_object);
}

// 处理所有普通对象，收集函数依赖关系
int analyze_task::process_regular_objects(
    mc::mutable_dict& objects,
    std::vector<std::shared_ptr<parsed_sr_object>>& parsed_objects,
    std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::shared_ptr<parsed_sr_object>>& object_index,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps,
    std::vector<std::string>& func_objects) {
    
    int failed_count = 0;
    
    for (auto& object_name : m_data->m_objects_queue) {
        // 跳过Func对象，稍后处理
        if (object_name.substr(0, 5) == "Func_") {
            func_objects.push_back(object_name);
            continue;
        }
        
        if (!process_single_regular_object(object_name, objects, object_info, func_to_apps, 
                                         parsed_objects, object_index)) {
            failed_count++;
        }
    }
    
    return failed_count;
}

// 处理所有函数对象，根据依赖关系分发给相应应用
int analyze_task::process_function_objects(
    mc::mutable_dict& objects,
    std::vector<std::shared_ptr<parsed_sr_func_object>>& parsed_func_objects,
    std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::set<std::string>>& func_to_apps,
    const std::vector<std::string>& func_objects) {
    
    int failed_count = 0;
    
    for (auto& func_object_name : func_objects) {
        // 从完整的函数对象名中提取基础函数名来查找依赖
        std::string base_func_name = extract_base_func_name(func_object_name);
        
        if (func_to_apps.find(base_func_name) == func_to_apps.end()) {
            // 没有应用依赖这个函数，跳过处理
            failed_count++;
            continue;
        }
        
        mc::mutable_dict func_props = objects[func_object_name].as_dict();
        auto& needed_apps = func_to_apps[base_func_name];
        
        // 函数对象也需要进行属性解析，为每个需要该函数的应用创建单独的实例
        for (const auto& app_name : needed_apps) {
            process_single_function_object_for_app(func_object_name, app_name, func_props, 
                                                  object_info, func_to_apps, parsed_func_objects);
        }
    }
    
    return failed_count;
}

void analyze_task::handle_parse_objects(
    mc::mutable_dict& objects, std::vector<std::shared_ptr<parsed_sr_object>>& parsed_objects, 
    std::vector<std::shared_ptr<parsed_sr_func_object>>& parsed_func_objects,
    std::unordered_map<std::string, instance_info_t>& object_info,
    std::unordered_map<std::string, std::shared_ptr<parsed_sr_object>>& object_index) {
    
    // 维护函数对象和需要它的应用的映射关系
    std::unordered_map<std::string, std::set<std::string>> func_to_apps;
    std::vector<std::string> func_objects; // 存储跳过的Func对象名
    
    // 第一轮遍历：处理非Func对象，收集函数依赖关系
    int failed_regular_count = process_regular_objects(objects, parsed_objects, object_info, 
                                                      object_index, func_to_apps, func_objects);
    
    // 第二轮遍历：处理Func对象，根据依赖关系分发给相应应用
    int failed_func_count = process_function_objects(objects, parsed_func_objects, object_info, 
                                                    func_to_apps, func_objects);
    
    int total_failed_count = failed_regular_count + failed_func_count;
    if (total_failed_count > 0) {
        wlog("ignore ${count} objects, position: ${position}",
             ("count", total_failed_count)("position", m_data->m_position));
    }
}

static void post_parse_objects(std::unordered_map<std::string, std::shared_ptr<parsed_sr_object>>& object_index,
                               std::unordered_map<std::string, std::vector<std::string>>&          object_children,
                               std::unordered_map<std::string, instance_info_t>&                   object_info) {
    for (auto& [object_name, children] : object_children) {
        if (object_index.find(object_name) != object_index.end()) {
            object_index[object_name]->extra_props[CHILDREN_KEY] = children;
        }
    }
    std::queue<std::string> object_queue;
    for (auto& [object_name, instance_info] : object_info) {
        if (instance_info.app == "hwdiscovery") {
            object_queue.push(object_name);
        }
    }
    while (!object_queue.empty()) {
        auto object_name = object_queue.front();
        object_queue.pop();
        auto instance_info = object_info[object_name];
        for (auto& ref_object : instance_info.references) {
            if (object_info.find(ref_object) != object_info.end() && !object_info[ref_object].framework) {
                object_info[ref_object].framework = true;
                object_queue.push(ref_object);
            }
        }
    }
    for (auto& [object_name, instance_info] : object_info) {
        if (object_index.find(object_name) != object_index.end() && instance_info.framework) {
            object_index[object_name]->extra_props["Framework"] = true;
        }
    }
}

std::unordered_set<std::string> analyze_task::get_buses_and_chips() {
    std::unordered_set<std::string> buses_and_chips;
    if (!m_data->m_management_topology.has_value()) {
        return buses_and_chips;
    }
    auto& topology = m_data->m_management_topology.value();
    for (auto& entry : topology) {
        if (!entry.value.is_dict()) {
            continue;
        }
        auto object = entry.value.as_dict();
        if (object.contains("Buses") && object["Buses"].is_array()) {
            auto buses = object["Buses"].as<std::vector<std::string>>();
            buses_and_chips.insert(buses.begin(), buses.end());
        } else if (object.contains("Chips") && object["Chips"].is_array()) {
            auto chips = object["Chips"].as<std::vector<std::string>>();
            buses_and_chips.insert(chips.begin(), chips.end());
        }
    }
    return buses_and_chips;
}

void analyze_task::delete_ignored_objects(std::vector<std::shared_ptr<parsed_sr_object>>& parsed_objects) {
    auto buses_and_chips = get_buses_and_chips();
    auto position        = m_data->m_position;
    auto callback        = [&buses_and_chips, position](const std::shared_ptr<parsed_sr_object>& obj) {
        auto class_name = csr_utils::get_class_name(obj->object_name);
        if (std::find(std::begin(IGNORED_CLASSES), std::end(IGNORED_CLASSES), class_name) !=
            std::end(IGNORED_CLASSES)) {
            return true;
        }
        if (buses_and_chips.find(obj->object_name) != buses_and_chips.end()) {
            return true;
        }
        return devmon::object_group_data::get_instance().is_device_object(position, obj->object_name);
    };
    parsed_objects.erase(std::remove_if(parsed_objects.begin(), parsed_objects.end(), callback), parsed_objects.end());
}

void analyze_task::handle_run() {
    if (!m_data->m_objects.has_value()) {
        return;
    }
    auto&                                                     objects = m_data->m_objects.value();
    std::unordered_map<std::string, instance_info_t>          object_info;
    std::unordered_map<std::string, std::vector<std::string>> object_children;
    pre_parse_objects(objects, object_info, object_children);
    std::vector<std::shared_ptr<parsed_sr_object>>                     parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>>                 parsed_func_objects;
    std::unordered_map<std::string, std::shared_ptr<parsed_sr_object>> object_index;
    handle_parse_objects(objects, parsed_objects, parsed_func_objects, object_info, object_index);
    post_parse_objects(object_index, object_children, object_info);
    delete_ignored_objects(parsed_objects);
    devmon::object_group_data::get_instance().save_objects(m_data->m_position, parsed_objects, parsed_func_objects);
}

} // namespace csr_parser
} // namespace devmon